package org.openmore.opc.service.impl;

import org.openmore.common.CommonUtils;
import org.openmore.common.exception.OpenmoreException;
import org.openmore.common.str.ChineseToEnglishUtil;
import org.openmore.opc.dao.RoleMapper;
import org.openmore.opc.dao.RolePermissionMapper;
import org.openmore.opc.dao.UserMapper;
import org.openmore.opc.dto.api.RoleDto;
import org.openmore.opc.entity.Role;
import org.openmore.opc.entity.RolePermission;
import org.openmore.opc.entity.User;
import org.openmore.opc.framework.ReferencedFieldProcessor;
import org.openmore.opc.service.RoleService;
import org.openmore.opc.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;

@Service
public class RoleServiceImpl extends BaseServiceImpl implements RoleService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private ReferencedFieldProcessor processor;

    public RoleDto convertToDto(Role entity){
        RoleDto dto = new RoleDto();
        BeanUtils.copyProperties(entity, dto);
        processor.processOne(dto);
        return dto;
    }

    public List<RoleDto> convertToDto(List<Role> entityList){
        Map<String, String> catchFullName = new HashMap<>();
        List<RoleDto> dtoList = new ArrayList<>();
        for (Role role: entityList) {
            RoleDto dto = new RoleDto();
            BeanUtils.copyProperties(role, dto);
            dtoList.add(dto);
        }
        processor.process(dtoList);
        return dtoList;
    }

    /**
     * 为一个角色指定权限列表，以逗号间隔
     *
     * @return
     */
    public void grantPermission(String roleId, String permissionList) {
        if (StringUtils.isEmpty(permissionList)) {
            throw new OpenmoreException("权限列表不能为空");
        }
        Example example = new Example(RolePermission.class);
        example.createCriteria().andEqualTo("roleId", roleId);
        rolePermissionMapper.deleteByExample(example);
        String[] perms = permissionList.split(",");
        for (String per : perms) {
            if ("-1".equals(per)) {
                continue;
            }
            if ("0".equals(per)) {
                continue;
            }
            RolePermission entity = new RolePermission();
            entity.setRoleId(roleId);
            entity.setPermissionId(per);
            entity.setCreatedTime(new Date());
            rolePermissionMapper.insert(entity);
        }
    }

    /**
     * root用户获得所有的角色列表，并且返回角色对应的社区信息
     * @return
     */
    public List<RoleDto> getDtoFullInfo(String name) {
        List<RoleDto> dtoList = roleMapper.selectDto(null, name);
        if (dtoList == null || dtoList.size() == 0) {
            return null;
        }
        processor.process(dtoList);
        return dtoList;
    }

    /**
     * 根据id获得实体对象
     *
     * @param id
     */
    @Override
    public Role getEntityById(String id) {
        Example example = new Example(Role.class);
        example.createCriteria().andEqualTo("id", id).andEqualTo("deleted", false);
        return roleMapper.selectOneByExample(example);
    }

    /**
     * 根据code获得实体对象
     */
    @Override
    public Role getEntityByCode(String code) {
        Example example = new Example(Role.class);
        example.createCriteria().andEqualTo("code", code).andEqualTo("deleted", false);
        return roleMapper.selectOneByExample(example);
    }

    /**
     * 根据id获得DTO对象
     *
     * @param id
     */
    @Override
    public RoleDto getDtoById(String id) {
        List<RoleDto> dtoList = roleMapper.selectDto(id, null);
        if (dtoList == null || dtoList.size() == 0) {
            return null;
        }
        return dtoList.get(0);
    }

    /**
     * 获得所有记录
     *
     * @return
     */
    @Override
    public List<RoleDto> selectAll(String id, String name) {
        return roleMapper.selectDto(id, name);
    }

    /**
     * 带UUID的插入
     * 所有的插入数据，都要调用这个实现
     *
     * @param dto
     */
    @Override
    public RoleDto insert(RoleDto dto) {
        Role entity = new Role();
        BeanUtils.copyProperties(dto, entity);
        if (StringUtils.isEmpty(entity.getCode())) {
//          加入随机，怕重复
            String code = ChineseToEnglishUtil.toHanyuPinyin(dto.getName()) + "_" + CommonUtils.randomString(4);
            entity.setCode(code);
        }
        beforeInsert(entity);
        roleMapper.insert(entity);
        insertLog("添加角色:" + dto.getName());
        dto.setId(entity.getId());
        return dto;
    }

    /**
     * 删除指定id的数据
     */
    @Override
    public void deleteById(String id) {
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("roleId", id);
        int count = userMapper.selectCountByExample(example);
        if (count > 0) {
            throw new OpenmoreException("当前角色下有员工，无法删除角色");
        }
        Role entity = this.getEntityById(id);
        if (entity != null) {
            example = new Example(Role.class);
            example.createCriteria().andEqualTo("id", id).andEqualTo("deleted", false);
            entity.setDeleted(true);
            roleMapper.updateByExampleSelective(entity, example);
            insertLog("删除角色:" + entity.getName());
        }
    }

    /**
     * 修改数据
     */
    @Override
    public void update(RoleDto dto) {
        if (null == dto) {
            throw new OpenmoreException(4001, "参数不能为空");
        }
        if(StringUtils.isEmpty(dto.getId())){
            throw new OpenmoreException(4001, "id不能为空");
        }
        Role entity = new Role();
        BeanUtils.copyProperties(dto, entity);
        Example example = new Example(Role.class);
        example.createCriteria().andEqualTo("id", entity.getId()).andEqualTo("deleted", false);
        beforeUpdate(entity);
        roleMapper.updateByExampleSelective(entity, example);
        insertLog("更新角色:" + dto.getName());
    }

    @Autowired
    private UserService userService;
    /**
     * 根据员工id获得角色列表
     * ############################################################################
     * # 仅在配置shiro权限时使用，其它时候，使用getPermissionsByStaffId，直接获得用户权限
     * ############################################################################
     *
     * @param email
     * @return
     */
    @Override
    public List<Role> getRolesByEmail(String tenantId, String email) {
        User user = userService.getUserByEmail(tenantId, email);
        if (user == null) {
            return null;
        }
        return roleMapper.getRolesByStaffId(user.getId());
    }
}